package com.demo.druid.component.datasource;

import com.demo.druid.component.datasource.annotation.DataSource;
import com.demo.druid.component.datasource.annotation.DataSourceKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * @author wangjianhua
 * @Description 动态获取并保存使用数据源
 * @date 2021/9/1/001 14:37
 **/
public class DynamicDataSourceContextHolder {

    private static final Logger logger= LoggerFactory.getLogger(DynamicDataSourceContextHolder.class);

    /**
     * 用于轮询的计数器
     */
    private static int counter = 0;

    /**
     * 给定一个主数据源进行初始化
     */
    private static final ThreadLocal<String> CONTEXT_HOLDER = ThreadLocal.withInitial(DataSourceKey.master::name);

    /**
     * 所有数据源的列表
     */
    public static List<Object> dataSourceKeys = new ArrayList<>();

    /**
     * 所有从数据源的列表
     */
    public static List<Object> slaveDataSourceKeys = new ArrayList<>();

    /**
     * 默认使用主数据源
     */
    public static void useMasterDataSource(){
        CONTEXT_HOLDER.set(DataSourceKey.master.name());
    }

    /**
     * 根据名称设置数据源
     *
     * @param key 数据源名称
     */
    public static void setDataSourceKey(String key) {
        CONTEXT_HOLDER.set(key);
    }

    /**
     * 简单实现一个轮询算法 从而轮番使用从数据源 降低数据库压力
     */
    public static void useSlaveDataSource(){
        try
        {
            int dataSourceKeyIndex = counter % slaveDataSourceKeys.size();
            CONTEXT_HOLDER.set(String.valueOf(slaveDataSourceKeys.get(dataSourceKeyIndex)));
            logger.info("选择数据源为:{}",slaveDataSourceKeys.get(dataSourceKeyIndex));
            counter ++;
        }
        catch (Exception e)
        {
            logger.info("选择从数据源失败,失败信息===> {}",e.getMessage());
            //保证可以查询
            useMasterDataSource();
            e.printStackTrace();
        }
    }

    /**
     * 获得正在使用的数据源
     * @return  数据源名字
     */
    public static String getDataSourceKey(){
        return CONTEXT_HOLDER.get();
    }

    /**
     * 清空数据源
     */
    public static void clearDataSourceKey(){
        logger.info("查询完毕 清空数据源====");
        CONTEXT_HOLDER.remove();
    }

    /**
     * 判断是否有该数据源
     * @param key 数据源名称
     * @return boolean
     */
    public static boolean containsDataSourceKey(String key){
        return dataSourceKeys.contains(key);
    }
}
